package com.example.ovulationperiodtracker.utils;

import com.example.ovulationperiodtracker.view.NoteUtils;
import com.github.mikephil.charting.data.BarEntry;

import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class SexStatisticsUtils {

    public static List<NoteUtils.DayNote> getAllNotes12() {
        LocalDate localDateStart = LocalDate.now().plusMonths(-12);
        List<NoteUtils.DayNote> allNotes = new ArrayList<>();
        LocalDate temp = LocalDate.now();
        while (temp.isAfter(localDateStart)) {
            allNotes.add(NoteUtils.getDayNote(temp));
            temp = temp.plusDays(-1);
        }

        return allNotes;
    }

    public static float allSexCount() {
        List<NoteUtils.DayNote> allNotes12 = getAllNotes12();
        int count = 0;
        for (int i = 0; i < allNotes12.size(); i++) {
            NoteUtils.DayNote dayNote = allNotes12.get(i);
            count = count + dayNote.sexCount;
        }
        return (float) count;
    }


    //每周平均性次数
    public static String getWeekAveSex() {
        LocalDate localDateStart = LocalDate.now().plusMonths(-12);
        long weekCount = ChronoUnit.WEEKS.between(localDateStart, LocalDate.now());
        float f = (allSexCount() / (float) weekCount);
        return String.format("%.2f", f);
    }

    //每月平均性次数
    public static String getMonthAveSex() {
        LocalDate localDateStart = LocalDate.now().plusMonths(-12);
        long monthCount = ChronoUnit.MONTHS.between(localDateStart, LocalDate.now());
        float f = (allSexCount() / (float) monthCount);
        return String.format("%.2f", f);
    }


    //所有高潮次数
    public static float allGaoCount() {
        List<NoteUtils.DayNote> allNotes12 = getAllNotes12();
        int count = 0;
        for (int i = 0; i < allNotes12.size(); i++) {
            NoteUtils.DayNote dayNote = allNotes12.get(i);
            count = count + dayNote.gaoCount;
        }
        return (float) count;
    }

    //每周高潮平均次数
    public static String getWeekAveGao() {
        LocalDate localDateStart = LocalDate.now().plusMonths(-12);
        long weekCount = ChronoUnit.WEEKS.between(localDateStart, LocalDate.now());
        float f = (allGaoCount() / (float) weekCount);
        return String.format("%.2f", f);
    }

    //每月高潮平均次数
    public static String getMonthAveGao() {
        LocalDate localDateStart = LocalDate.now().plusMonths(-12);
        long monthCount = ChronoUnit.MONTHS.between(localDateStart, LocalDate.now());
        float f = (allGaoCount() / (float) monthCount);
        return String.format("%.2f", f);
    }


    //易孕期所有的性和高
    public static float[] getYiYunSexGaoCount() {

        int sexCount = 0;
        int gaoCount = 0;

        int huangTiQi = NoteUtils.getHuangTiQi();

        List<NoteUtils.DayNote> allNotes12 = getAllNotes12();
        for (int i = 0; i < allNotes12.size(); i++) {

            NoteUtils.DayNote dayNote = allNotes12.get(i);
            // 排卵日 下次月经日-14天（黄体期），易孕日是排卵日前5天和后4天 共10天
            if (dayNote.jingStart == 1) {
                LocalDate tempDate = LocalDate.parse(dayNote.date);
                //排卵日
                LocalDate paiLuanRi = tempDate.plusDays(-huangTiQi);
                LocalDate yiYunRiStart = paiLuanRi.plusDays(-6);
                LocalDate yiYunRiEnd = paiLuanRi.plusDays(+4);

                LocalDate temp = yiYunRiEnd;
                while (temp.isAfter(yiYunRiStart)) {
                    NoteUtils.DayNote dayNote1 = NoteUtils.getDayNote(temp);
                    sexCount = sexCount + dayNote1.sexCount;
                    gaoCount = gaoCount + dayNote1.gaoCount;
                    temp = temp.plusDays(-1);
                }
            }
        }

        return new float[]{(float) sexCount, (float) gaoCount};
    }


    //每月易孕期性和高潮平均次数
    public static String[] getYiYunMonthAve() {
        LocalDate localDateStart = LocalDate.now().plusMonths(-12);
        long monthCount = ChronoUnit.MONTHS.between(localDateStart, LocalDate.now());

        float[] yiYunSexGaoCount = getYiYunSexGaoCount();

        float f1 = (yiYunSexGaoCount[0] / (float) monthCount);
        float f2 = (yiYunSexGaoCount[1] / (float) monthCount);
        return new String[]{String.format("%.2f", f1), String.format("%.2f", f2)};
    }


    //每周易孕期性和高潮平均次数
    public static String[] getYiYunWeekAve() {
        LocalDate localDateStart = LocalDate.now().plusMonths(-12);
        long weekCount = ChronoUnit.WEEKS.between(localDateStart, LocalDate.now());
        float[] yiYunSexGaoCount = getYiYunSexGaoCount();
        float f1 = (yiYunSexGaoCount[0] / (float) weekCount);
        float f2 = (yiYunSexGaoCount[1] / (float) weekCount);
        return new String[]{String.format("%.2f", f1), String.format("%.2f", f2)};
    }


    //高潮概率
    public static String getGaoSex() {
        float allGaoCount = allGaoCount();

        if (allGaoCount == 0) {
            return "0.00%";
        }
        float allSexCount = allSexCount();
        float f = (allGaoCount / allSexCount) * 100;
        return String.format("%.2f", f) + "%";
    }


    //几个月内周期的平均
    public static double getAvgperiodLength(int months) {
        LocalDate endDate;
        LocalDate startDate;
        if (months == -1) {
            endDate = LocalDate.MAX;
            startDate = LocalDate.MIN;
        } else {
            endDate = LocalDate.now();
            startDate = endDate.plusMonths(-months);
        }

        List<LocalDate> allJingStart = NoteUtils.getAllJingStart();

        List<LocalDate> filteredDates = allJingStart.stream()
                .filter(date -> !date.isBefore(startDate) && !date.isAfter(endDate))
                .collect(Collectors.toList());

        if (filteredDates.size() < 2) {
            return 0.0f;
        }

        // 使用 IntStream 一次性计算所有间隔和平均值
        double averageInterval = IntStream.range(0, filteredDates.size() - 1)
                .mapToLong(i -> ChronoUnit.DAYS.between(
                        filteredDates.get(i + 1),
                        filteredDates.get(i)
                ))
                .average()
                .orElse(0.0);
        return averageInterval;
    }


    /**
     * 计算月经周期间隔的最大和最小天数
     *
     * @param months 分析的时间范围（月数），-1表示全部时间
     * @return int[2] 数组，下标0为最大间隔天数，下标1为最小间隔天数
     */
    public static int[] calculateMaxMinInterval(int months) {
        // 设置时间范围
        LocalDate endDate;
        LocalDate startDate;
        if (months == -1) {
            endDate = LocalDate.MAX;
            startDate = LocalDate.MIN;
        } else {
            endDate = LocalDate.now();
            startDate = endDate.plusMonths(-months);
        }
        List<LocalDate> allJingStart = NoteUtils.getAllJingStart();
        // 筛选日期
        List<LocalDate> filteredDates = allJingStart.stream()
                .filter(date -> !date.isBefore(startDate) && !date.isAfter(endDate))
                .sorted()
                .collect(Collectors.toList());

        // 初始化结果数组
        int[] result = new int[2];

        // 检查数据是否足够
        if (filteredDates == null || filteredDates.size() < 2) {
            // 数据不足时返回默认值
            result[0] = 0; // 最大间隔
            result[1] = 0; // 最小间隔
            return result;
        }

        // 计算所有间隔
        List<Integer> intervals = new ArrayList<>();
        for (int i = 0; i < filteredDates.size() - 1; i++) {
            long days = ChronoUnit.DAYS.between(filteredDates.get(i), filteredDates.get(i + 1));
            intervals.add((int) days);
        }

        // 找出最大和最小间隔
        int maxInterval = intervals.stream()
                .mapToInt(Integer::intValue)
                .max()
                .orElse(0);

        int minInterval = intervals.stream()
                .mapToInt(Integer::intValue)
                .min()
                .orElse(0);

        result[0] = maxInterval;
        result[1] = minInterval;

        return result;
    }


    //平均经期长度
    public static double getAvgJingLength() {

        List<LocalDate> allJingStart = NoteUtils.getAllJingStart();
        List<LocalDate> allJingEnd = NoteUtils.getAllJingEnd();
        if (allJingStart.size() < 2 || allJingEnd.size() < 2) {
            return 0;
        }

        List<Integer> lengs = new ArrayList<>();

        for (int i = 0; i < allJingStart.size(); i++) {
            LocalDate start = allJingStart.get(i);
            //找出距离月经开始日 10天内最大的日期，既为月经结束日，如果没有则按照固定的长度预测
            LocalDate end = allJingEnd.stream()
                    .filter(date -> start.isBefore(date) && start.plusDays(10).isAfter(date))
                    .max(LocalDate::compareTo).orElse(null);

            //没有明确记录结束日期的不计入
            if (end != null) {
                int daysDifference = (int) ChronoUnit.DAYS.between(start, end);
                lengs.add(daysDifference);
            }
        }
        double average = lengs.stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0.0);

        return average;
    }


}
